#include "hook.h"

#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <time.h>
#include <sys/ioctl.h>
#include <execinfo.h>
#include <pthread.h>
#include <string.h>

#include <rte_version.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>


void udp_fill_data(p_main_flow mflow, char* buf, uint16_t size)
{
        struct rte_ether_hdr *eth;
        struct rte_ipv4_hdr  *iph;
        struct rte_udp_hdr   *udph;
	uint16_t eth_l  = sizeof(struct rte_ether_hdr);
	uint16_t iph_l  = sizeof(struct rte_ipv4_hdr);
	uint16_t udph_l = sizeof(struct rte_udp_hdr);

	memset(buf, 0, size);

	eth = (struct rte_ether_hdr*)buf;
        //// <21
        //rte_memcpy(eth->d_addr.addr_bytes, dst_mac, RTE_ETHER_ADDR_LEN);
        //rte_memcpy(eth->s_addr.addr_bytes, src_mac, RTE_ETHER_ADDR_LEN);
        // >=21
        rte_memcpy(eth->dst_addr.addr_bytes, mflow->m_socket_io.r_remote_addr.sll_addr, RTE_ETHER_ADDR_LEN);
        rte_memcpy(eth->src_addr.addr_bytes, mflow->m_socket_io.r_local_addr.sll_addr, RTE_ETHER_ADDR_LEN);
        eth->ether_type = htons(RTE_ETHER_TYPE_IPV4);

        iph = (struct rte_ipv4_hdr*)(eth+1);
        iph->version_ihl = 0x45;
        iph->type_of_service = 0;
        iph->total_length = htons(size - eth_l);
        iph->packet_id = 0;
        iph->fragment_offset = 0;
        iph->time_to_live = 64;
        iph->next_proto_id = IPPROTO_UDP;
        iph->src_addr = inet_addr(mflow->m_flow_state.sstate.local_ip);
        iph->dst_addr = inet_addr(mflow->m_flow_state.sstate.remote_ip);

        udph = (struct rte_udp_hdr*)(iph+1);
        udph->src_port = htons(mflow->m_flow_state.sstate.local_port);
        udph->dst_port = htons(mflow->m_flow_state.sstate.remote_port);
        udph->dgram_len = htons(size - eth_l - iph_l);

	udph->dgram_cksum = 0;
        udph->dgram_cksum = rte_ipv4_udptcp_cksum(iph, udph);
        
	iph->hdr_checksum = 0;
        iph->hdr_checksum = rte_ipv4_cksum(iph);
}

